import 'package:drift/drift.dart';

import '../../database/app_database.dart' as db;
import '../../models/project_model.dart' as project_model;
import '../../models/todo_model.dart' as todo_model;
import '../../models/note_model.dart' as note_model;
import '../../models/user_model.dart';

/// 本地数据源
class LocalDataSource {
  final db.AppDatabase _database;

  LocalDataSource(this._database);

  // ==================== 用户相关 ====================

  /// 获取所有用户
  Future<List<UserModel>> getAllUsers() async {
    final users = await _database.getAllUsers();
    return users.map((user) => _userFromDatabase(user)).toList();
  }

  /// 根据ID查找用户
  Future<UserModel?> findUserById(int id) async {
    final user = await _database.findUserById(id);
    return user != null ? _userFromDatabase(user) : null;
  }

  /// 保存用户
  Future<void> saveUser(UserModel user) async {
    final userCompanion = db.UsersCompanion(
      id: Value(user.id),
      username: Value(user.username),
      email: Value(user.email),
      role: Value(user.role),
      isActive: Value(user.isActive),
      createTime: Value(user.createTime),
      updateTime: Value(user.updateTime ?? DateTime.now()),
    );

    await _database.insertUser(userCompanion);
  }

  /// 删除用户
  Future<void> deleteUser(int id) async {
    await _database.deleteUser(id);
  }

  // ==================== 项目相关 ====================

  /// 获取所有项目
  Future<List<project_model.ProjectModel>> getAllProjects() async {
    final projects = await _database.getAllProjects();
    return projects.map((project) => _projectFromDatabase(project)).toList();
  }

  /// 根据ID查找项目
  Future<project_model.ProjectModel?> findProjectById(int id) async {
    final project = await _database.findProjectById(id);
    return project != null ? _projectFromDatabase(project) : null;
  }

  /// 保存项目
  Future<void> saveProject(project_model.ProjectModel project) async {
    final projectCompanion = db.ProjectsCompanion(
      id: Value(project.id),
      projectName: Value(project.projectName),
      description: Value(project.description),
      status: Value(project.status.code),
      ownerId: Value(project.creatorId),
      createTime: Value(project.createTime),
      updateTime: Value(project.updateTime ?? DateTime.now()),
    );

    await _database.insertProject(projectCompanion);
  }

  /// 删除项目
  Future<void> deleteProject(int id) async {
    await _database.deleteProject(id);
  }

  /// 根据创建者ID获取项目
  Future<List<project_model.ProjectModel>> getProjectsByCreatorId(
      int creatorId) async {
    final projects = await _database.getAllProjects();
    final filteredProjects =
        projects.where((project) => project.ownerId == creatorId).toList();
    return filteredProjects
        .map((project) => _projectFromDatabase(project))
        .toList();
  }

  // ==================== 待办事项相关 ====================

  /// 获取所有待办事项
  Future<List<todo_model.TodoModel>> getAllTodos() async {
    final todos = await _database.getAllTodos();
    return todos.map((todo) => _todoFromDatabase(todo)).toList();
  }

  /// 根据ID查找待办事项
  Future<todo_model.TodoModel?> findTodoById(int id) async {
    final todo = await _database.findTodoById(id);
    return todo != null ? _todoFromDatabase(todo) : null;
  }

  /// 保存待办事项
  Future<void> saveTodo(todo_model.TodoModel todo) async {
    final todoCompanion = db.TodosCompanion(
      id: Value(todo.id),
      title: Value(todo.title),
      description: Value(todo.description),
      status: Value(todo.status.code),
      projectId: Value(todo.projectId),
      assigneeId: Value(todo.assigneeId),
      reporterId: Value(todo.reporterId),
      estimatedHours: Value(todo.estimatedHours?.toInt()),
      actualHours: Value(todo.actualHours?.toInt()),
      createTime: Value(todo.createTime),
      updateTime: Value(todo.updateTime ?? DateTime.now()),
      dueDate: Value(todo.dueDate),
    );

    await _database.insertTodo(todoCompanion);
  }

  /// 删除待办事项
  Future<void> deleteTodo(int id) async {
    await _database.deleteTodo(id);
  }

  /// 根据项目ID获取待办事项
  Future<List<todo_model.TodoModel>> getTodosByProjectId(int projectId) async {
    final todos = await _database.getTodosByProjectId(projectId);
    return todos.map((todo) => _todoFromDatabase(todo)).toList();
  }

  /// 根据分配人ID获取待办事项
  Future<List<todo_model.TodoModel>> getTodosByAssigneeId(
      int assigneeId) async {
    final todos = await _database.getTodosByAssigneeId(assigneeId);
    return todos.map((todo) => _todoFromDatabase(todo)).toList();
  }

  /// 获取待办事项（带过滤条件）
  Future<List<todo_model.TodoModel>> getTodos({
    int? projectId,
    todo_model.TodoStatus? status,
    int? assigneeId,
  }) async {
    List<todo_model.TodoModel> result = await getAllTodos();

    if (projectId != null) {
      result = result.where((todo) => todo.projectId == projectId).toList();
    }

    if (status != null) {
      result = result.where((todo) => todo.status == status).toList();
    }

    if (assigneeId != null) {
      result = result.where((todo) => todo.assigneeId == assigneeId).toList();
    }

    return result;
  }

  /// 根据ID获取待办事项
  Future<todo_model.TodoModel> getTodo(int id) async {
    final todo = await findTodoById(id);
    if (todo == null) {
      throw Exception('待办事项不存在');
    }
    return todo;
  }

  /// 根据项目ID获取待办事项
  Future<List<todo_model.TodoModel>> getProjectTodos(int projectId) async {
    return await getTodosByProjectId(projectId);
  }

  /// 获取我的待办事项
  Future<List<todo_model.TodoModel>> getMyTodos() async {
    // 这里应该根据当前用户ID来过滤，暂时返回所有待办事项
    return await getAllTodos();
  }

  // ==================== 笔记相关 ====================

  /// 获取所有笔记
  Future<List<note_model.Note>> getAllNotes() async {
    final notes = await _database.getAllNotes();
    return notes.map((note) => _noteFromDatabase(note)).toList();
  }

  /// 根据ID查找笔记
  Future<note_model.Note?> findNoteById(int id) async {
    final note = await _database.findNoteById(id);
    return note != null ? _noteFromDatabase(note) : null;
  }

  /// 保存笔记
  Future<void> saveNote(note_model.Note note) async {
    final noteCompanion = db.NotesCompanion(
      // 修复：应该是NotesCompanion
      id: Value(note.id),
      projectId: Value(note.projectId),
      todoId: Value(note.todoId),
      title: Value(note.title),
      content: Value(note.content),
      noteType: Value(note.noteType.code),
      tags: Value(note.tags.join(',')),
      authorId: Value(note.authorId),
      isPublic: Value(note.isPublic),
      createTime: Value(note.createTime),
      updateTime: Value(note.updateTime ?? DateTime.now()),
    );

    await _database.insertNote(noteCompanion);
  }

  /// 删除笔记
  Future<void> deleteNote(int id) async {
    await _database.deleteNote(id);
  }

  /// 根据项目ID获取笔记
  Future<List<note_model.Note>> getNotesByProjectId(int projectId) async {
    final notes = await _database.getNotesByProjectId(projectId);
    return notes.map((note) => _noteFromDatabase(note)).toList();
  }

  /// 根据待办ID获取笔记
  Future<List<note_model.Note>> getNotesByTodoId(int todoId) async {
    final notes = await _database.getNotesByTodoId(todoId);
    return notes.map((note) => _noteFromDatabase(note)).toList();
  }

  /// 搜索笔记
  Future<List<note_model.Note>> searchNotes(String keyword) async {
    final notes = await _database.searchNotes(keyword);
    return notes.map((note) => _noteFromDatabase(note)).toList();
  }

  /// 根据标签获取笔记
  Future<List<note_model.Note>> getNotesByTags(List<String> tags) async {
    // 在本地数据库中搜索包含指定标签的笔记
    final allNotes = await getAllNotes();
    return allNotes.where((note) {
      return tags.any((tag) => note.tags.contains(tag));
    }).toList();
  }

  /// 根据条件获取笔记
  Future<List<note_model.Note>> getNotes({
    int? projectId,
    int? todoId,
    String? keyword,
    List<String>? tags,
  }) async {
    List<note_model.Note> result = await getAllNotes();

    if (projectId != null) {
      result = result.where((note) => note.projectId == projectId).toList();
    }

    if (todoId != null) {
      result = result.where((note) => note.todoId == todoId).toList();
    }

    if (keyword != null && keyword.isNotEmpty) {
      result = result
          .where((note) =>
              note.title.contains(keyword) || note.content.contains(keyword))
          .toList();
    }

    if (tags != null && tags.isNotEmpty) {
      result = result.where((note) {
        return tags.any((tag) => note.tags.contains(tag));
      }).toList();
    }

    return result;
  }

  // ==================== 转换方法 ====================

  /// 将数据库User转换为UserModel
  UserModel _userFromDatabase(db.User user) {
    return UserModel(
      id: user.id,
      username: user.username,
      email: user.email,
      role: user.role,
      isActive: user.isActive,
      createTime: user.createTime,
      updateTime: user.updateTime,
    );
  }

  /// 将数据库Project转换为ProjectModel
  project_model.ProjectModel _projectFromDatabase(db.Project project) {
    return project_model.ProjectModel(
      id: project.id,
      projectName: project.projectName,
      description: project.description,
      status: project_model.ProjectStatus.fromCode(project.status),
      priority: project_model.Priority.medium, // 数据库中没有优先级字段，使用默认值
      creatorId: project.ownerId,
      createTime: project.createTime,
      updateTime: project.updateTime,
    );
  }

  /// 将数据库Todo转换为TodoModel
  todo_model.TodoModel _todoFromDatabase(db.Todo todo) {
    return todo_model.TodoModel(
      id: todo.id,
      projectId: todo.projectId,
      title: todo.title,
      description: todo.description,
      status: todo_model.TodoStatus.fromCode(todo.status),
      priority: todo_model.Priority.medium, // 数据库中没有优先级字段，使用默认值
      todoType: todo_model.TodoType.develop, // 数据库中没有类型字段，使用默认值
      reporterId: todo.reporterId,
      assigneeId: todo.assigneeId,
      dueDate: todo.dueDate,
      estimatedHours: todo.estimatedHours?.toDouble(),
      actualHours: todo.actualHours?.toDouble(),
      createTime: todo.createTime,
      updateTime: todo.updateTime,
    );
  }

  /// 将数据库Note转换为Note
  note_model.Note _noteFromDatabase(dynamic note) {
    return note_model.Note(
      id: note.id,
      projectId: note.projectId,
      todoId: note.todoId,
      title: note.title,
      content: note.content,
      noteType: note_model.NoteType.fromCode(note.noteType),
      tags: note.tags != null
          ? note.tags!.split(',').map((tag) => tag.trim()).toList()
          : [],
      authorId: note.authorId,
      isPublic: note.isPublic,
      createTime: note.createTime,
      updateTime: note.updateTime,
    );
  }
}
